home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / serweb03.zip / SERWEVW.CPP < prev    next >
C/C++ Source or Header  |  1993-10-12  |  29KB  |  824 lines

  1. // serwevw.cpp : implementation of the CSerwebView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "serweb.h"
  6.  
  7. #include "serwedoc.h"
  8. #include "serwevw.h"
  9.  
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char BASED_CODE THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CSerwebView
  17.  
  18. IMPLEMENT_DYNCREATE(CSerwebView, CScrollView)
  19.  
  20. BEGIN_MESSAGE_MAP(CSerwebView, CScrollView)
  21.     //{{AFX_MSG_MAP(CSerwebView)
  22.       ON_MESSAGE(CLIENT_MSG, OnWWWClientMsg) 
  23.         ON_MESSAGE(INCOMING_MSG, OnWWWServerMsg) 
  24.     ON_COMMAND(ID_PERIOD_OK, OnPeriodOk)
  25.     ON_COMMAND(ID_SERVER_INACT, OnServerInact)
  26.     ON_COMMAND(ID_UPDATE_STAT, OnUpdateStat)
  27.     ON_WM_TIMER()
  28.     //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CSerwebView construction/destruction
  33.  
  34. CSerwebView::CSerwebView()
  35. {
  36.     // TODO: add construction code here
  37. }
  38.  
  39. CSerwebView::~CSerwebView()
  40. {
  41.   int Loop;
  42.  
  43.     // Close the listening server first ....                      
  44.     if (WWWServer != INVALID_SOCKET)
  45.       if (closesocket(WWWServer) == SOCKET_ERROR)
  46.         {
  47.            sprintf(buf, "Windows Socket error %d:  Couldn't close the server socket.", WSAGetLastError());
  48.            MessageBox( buf,  AfxGetAppName(), MB_OK);
  49.         }
  50.                                             
  51.     // Close any outstanding connections .....                                        
  52.     for (Loop = 0; Loop < HowManyClients; Loop++)
  53.        if (WWWConv[Loop].State != SOCK_FREE)
  54.          if (closesocket(WWWConv[Loop].CliSock) == SOCKET_ERROR)
  55.            {
  56.               sprintf(buf, "Windows Socket error %d:  Couldn't close a client socket.", WSAGetLastError());
  57.               MessageBox( buf,  AfxGetAppName(), MB_OK);
  58.            } 
  59.            
  60.     // Kill the timer ...
  61.     KillTimer(IdEv);
  62.     
  63. }    
  64.  
  65. //////////////////////////////////////////////////////////////////////////////
  66. void CSerwebView::OnInitialUpdate()
  67. {                           
  68.     int err, Loop;
  69.     CClientDC dc(this);
  70.     TEXTMETRIC tm;
  71.     CRect MyWin;
  72.  
  73.   CWnd* pParent = GetParent();
  74.   CMenu* pMenu = pParent->GetMenu();                   
  75.        
  76.     // ************ Set the proper options here ......
  77.     
  78.     WWWPort = AfxGetApp()->GetProfileInt("SERWEB", "PortNumber",80);
  79.     HowManyClients = AfxGetApp()->GetProfileInt("SERWEB", "HowManyClients",5);
  80.     if (HowManyClients > MAX_CLIENTS)     // Can't have more than we have storage for .....
  81.       {
  82.          HowManyClients = MAX_CLIENTS;
  83.          PrintSt("  Requested more than 10 clients.  Resetting to 10.\n");
  84.       }
  85.     if (AfxGetApp()->GetProfileInt("SERWEB", "ClosedServer",0) == 1)
  86.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_CHECKED);
  87.     else
  88.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_UNCHECKED);
  89.  
  90.     if (AfxGetApp()->GetProfileInt("SERWEB", "PeriodAllowed",1) == 0)
  91.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_CHECKED);
  92.     else
  93.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_UNCHECKED);
  94.  
  95.     if (AfxGetApp()->GetProfileInt("SERWEB", "PrintOut",1) == 1)
  96.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_CHECKED);
  97.     else
  98.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_UNCHECKED);
  99.  
  100.     SendDir          = AfxGetApp()->GetProfileString("SERWEB", "SendDir","C:\\SERWEB");
  101.     FileNotExistMsg  = AfxGetApp()->GetProfileString("SERWEB", "FileNotExistMsg","C:\\SERWEB\\nofile.htm");
  102.     ClosedServerMsg  = AfxGetApp()->GetProfileString("SERWEB", "ClosedServerMsg","C:\\SERWEB\\closed.htm");
  103.     PeriodAllowedMsg = AfxGetApp()->GetProfileString("SERWEB", "PeriodAllowedMsg","C:\\SERWEB\\period.htm");
  104.  
  105.     // SIze the frame window to a normal size and set the scrollers ....
  106.     
  107.     dc.GetTextMetrics(&tm);                        
  108.     SetScrollSizes( MM_TEXT, CSize(0,0), CSize(0,(MAX_LINES*tm.tmHeight)), CSize(0, tm.tmHeight)); 
  109.     
  110.     GetWindowRect( MyWin );
  111.     GetParentFrame()->MoveWindow( MyWin.left, MyWin.top, (COLUMN_MAX*tm.tmAveCharWidth), (24*tm.tmHeight), FALSE);
  112.  
  113.  
  114.     // Initialize WinSocket code here ......
  115.     
  116.     WWWServer = INVALID_SOCKET;              // The server is not connected yet ....
  117.  
  118.      // and set all sockets structures to not used ....
  119.  
  120.      for (Loop = 0; Loop < HowManyClients; Loop++)
  121.        WWWConv[Loop].State = SOCK_FREE;
  122.  
  123.     PrintSt("\n");
  124.     WWWServer = socket(AF_INET, SOCK_STREAM, 0);
  125.     if (WWWServer == INVALID_SOCKET)
  126.       {
  127.          sprintf(buf, "Windows Socket error %d:  Couldnot create server socket.", WSAGetLastError());
  128.          PrintSt("  Initialization incorrect \n\n  Please correct the problem and restart.\n");
  129.          MessageBox( buf,  AfxGetAppName(), MB_OK);
  130.          return;   
  131.        }
  132.      
  133.     srv_addr.sin_family = AF_INET;
  134.     srv_addr.sin_addr.s_addr = INADDR_ANY;   
  135.     srv_addr.sin_port = htons(WWWPort);
  136.     
  137.     if (bind(WWWServer, (LPSOCKADDR)&srv_addr, sizeof(srv_addr)) == SOCKET_ERROR)
  138.        {
  139.          sprintf(buf, "Windows Socket error %d:  Couldn't bind the server socket.", WSAGetLastError());
  140.          PrintSt("  Initialization incorrect \n\n  Please correct the problem and restart.\n");
  141.          MessageBox( buf,  AfxGetAppName(), MB_OK);
  142.          return;   
  143.        }
  144.          
  145.       err = WSAAsyncSelect(WWWServer, m_hWnd, INCOMING_MSG, FD_ACCEPT);
  146.       if (err == SOCKET_ERROR) 
  147.        {
  148.          sprintf(buf, "Windows Socket error %d:  WSAAsyncSelect code did not work for the server.", WSAGetLastError());
  149.          PrintSt("  Initialization incorrect \n\n  Please correct the problem and restart.\n");
  150.          MessageBox( buf,  AfxGetAppName(), MB_OK);
  151.          return;   
  152.        }
  153.  
  154.     if (listen(WWWServer,2) == SOCKET_ERROR)
  155.       {
  156.          sprintf(buf, "Windows Socket error %d:  Couldn't setup the server to listen for clients.", WSAGetLastError());
  157.          PrintSt("  Initialization incorrect \n\n  Please correct the problem and restart.\n");
  158.          MessageBox( buf,  AfxGetAppName(), MB_OK);
  159.          return;   
  160.        }
  161.      
  162.      
  163.      PrintSt("  Initialization was OK \n  Waiting for connections\n");  
  164.      SetTimer(IdEv, TIME_TO_CHECK, NULL);
  165. return;
  166. }
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169. // CSerwebView drawing
  170.  
  171. void CSerwebView::OnDraw(CDC* pDC)
  172. {
  173.     CSerwebDoc* pDoc = GetDocument();
  174.     TEXTMETRIC tm;
  175.     int yval;
  176.     CSize PositionHold;
  177.     
  178.     pDC->GetTextMetrics(&tm);
  179.     yval = 0;
  180.     for (int loop_index = 0; loop_index <= pDoc->line_number; loop_index++)
  181.       {
  182.         pDC->TextOut(0,yval,pDoc->data_string[loop_index], pDoc->data_string[loop_index].GetLength());
  183.         yval += tm.tmHeight;
  184.       }
  185.      
  186. /*     // Display cursor    ..........
  187.      PositionHold = pDC->GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  188.      pDC->BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  189. */
  190.      SetScrollSizes( MM_TEXT, CSize(0, ((int) pDoc->line_number+1) * tm.tmHeight));
  191. }
  192.  
  193.  
  194.  
  195. /////////////////////////////////////////////////////////////////////////////
  196. // CSerwebView diagnostics
  197.  
  198. #ifdef _DEBUG
  199. void CSerwebView::AssertValid() const
  200. {
  201.     CView::AssertValid();
  202. }
  203.  
  204. void CSerwebView::Dump(CDumpContext& dc) const
  205. {
  206.     CView::Dump(dc);
  207. }
  208.  
  209. CSerwebDoc* CSerwebView::GetDocument() // non-debug version is inline
  210. {
  211.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSerwebDoc)));
  212.     return (CSerwebDoc*) m_pDocument;
  213. }
  214.  
  215. #endif //_DEBUG
  216.  
  217. /////////////////////////////////////////////////////////////////////////////
  218. // CSerwebView message handlers
  219.  
  220. void CSerwebView::PrintChar(char nChar, char OutputIt)
  221. {
  222.   CSerwebDoc* pDoc = GetDocument();                 
  223.   CClientDC dc(this);
  224.   TEXTMETRIC tm;
  225.   CPoint Position, Origin;
  226.   CSize PositionHold;
  227.   CRect MyWindowSize;
  228.   CWnd* pParent = GetParent();
  229.   CMenu* pMenu = pParent->GetMenu();                   
  230.        
  231.    // No need to update the stuff .............................
  232.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  233.      return;
  234.      
  235.   OnPrepareDC(&dc);       
  236.   dc.GetTextMetrics(&tm);                        
  237. /*  if (OutputIt != 'n')
  238.    {
  239.      PositionHold = dc.GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  240.      dc.BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  241.    }                                                                 
  242. */
  243.   if (nChar =='\n')
  244.     {  
  245.       pDoc->column_number = 0;          // we are on the left now
  246.       if (pDoc->line_number == (MAX_LINES-1))
  247.         {
  248.           for (int loop_index=0; loop_index < MAX_LINES; loop_index++)
  249.             {
  250.               pDoc->data_string[loop_index] = pDoc->data_string[loop_index+1];
  251.             }
  252.           pDoc->data_string[loop_index].Empty;
  253.           pDoc->UpdateAllViews(this, 0L, 0);
  254.         }
  255.       else
  256.         pDoc->line_number++;
  257.       SetScrollSizes( MM_TEXT, CSize(0, ((int) pDoc->line_number+1) * tm.tmHeight));
  258.     }
  259.   else
  260.     {
  261.       if (pDoc->column_number++ >= COLUMN_MAX)
  262.         {
  263.            pDoc->column_number = 1;
  264.            if (pDoc->line_number == (MAX_LINES-1))
  265.              {
  266.                for (int loop_index=0; loop_index < MAX_LINES; loop_index++)
  267.                  {
  268.                     pDoc->data_string[loop_index] = pDoc->data_string[loop_index+1];
  269.                  }
  270.                pDoc->data_string[loop_index].Empty;
  271.                pDoc->UpdateAllViews(this, 0L, 0);
  272.              }
  273.            else
  274.              pDoc->line_number++;
  275.         }   
  276.       pDoc->data_string[pDoc->line_number] += nChar;
  277.       if (OutputIt != 'n')
  278.         dc.TextOut(0, (int) pDoc->line_number * tm.tmHeight,
  279.                    pDoc->data_string[pDoc->line_number],
  280.                    pDoc->data_string[pDoc->line_number].GetLength());
  281.                    
  282.     }                             
  283.     
  284.   // Scroll so user can see the line just outputted ...........
  285.   
  286.   if (OutputIt != 'n')
  287.    {
  288.     Position = GetScrollPosition(); 
  289.     if ((int) pDoc->line_number * tm.tmHeight < Position.y)
  290.       {
  291.         Position.y = (int) pDoc->line_number * tm.tmHeight;
  292.         ScrollToPosition( Position );
  293.       }
  294.     else
  295.       {
  296.         CScrollView::GetClientRect( MyWindowSize);                            
  297.         if ( (( (int) pDoc->line_number * tm.tmHeight) + tm.tmHeight) > MyWindowSize.bottom)
  298.           {                
  299.             Origin = dc.GetViewportOrg();  
  300.             Position.x = Origin.x;
  301.             Position.y = ((int) pDoc->line_number * tm.tmHeight) + tm.tmHeight - MyWindowSize.bottom;
  302.             ScrollToPosition( Position );
  303.            }
  304.         }    
  305.  
  306. /*      // Draw the cursor now ....
  307.       PositionHold = dc.GetTextExtent(pDoc->data_string[pDoc->line_number], (int) pDoc->column_number);
  308.       dc.BitBlt((PositionHold.cx+2), (int) pDoc->line_number * tm.tmHeight, tm.tmAveCharWidth, tm.tmHeight, NULL, 0, 0, DSTINVERT);
  309. */    }
  310.     
  311. }
  312.                                                         
  313. ////////////////////////////////////////////////////////////////////////////////////////
  314. void CSerwebView::PrintSt( CString StToPrint)
  315.  
  316. {
  317.   CSerwebDoc* pDoc = GetDocument();                 
  318.  
  319.   int Loop=0;  
  320.   CWnd* pParent = GetParent();
  321.   CMenu* pMenu = pParent->GetMenu();                   
  322.        
  323.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  324.      return;
  325.      
  326.    
  327.    if (StToPrint.GetLength() == 0)
  328.      return;
  329.    for ( Loop = 0; Loop < (StToPrint.GetLength()-1); Loop++)
  330.       PrintChar( StToPrint[Loop], 'n');
  331.    PrintChar( StToPrint[Loop], 'y');
  332.    pDoc->UpdateAllViews(NULL, 0L, 0);
  333. }
  334.  
  335. void CSerwebView::PrintSt( char* AString)
  336.  
  337. {
  338.   CSerwebDoc* pDoc = GetDocument();                 
  339.  
  340.   int Loop;  
  341.   CWnd* pParent = GetParent();
  342.   CMenu* pMenu = pParent->GetMenu();                   
  343.        
  344.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  345.      return;
  346.      
  347.    if (AString == NULL)
  348.      return;
  349.    for ( Loop = 0; AString[Loop+1] != NULL; Loop++)
  350.       PrintChar( AString[Loop], 'n');
  351.    PrintChar( AString[Loop], 'y');
  352.    pDoc->UpdateAllViews(NULL, 0L, 0);
  353. }
  354.  
  355. ////////////////////////////////////////////////////////////////////////////////////////
  356. void CSerwebView::OnUpdate(CView*, LPARAM, CObject*)
  357. {                                              
  358.   Invalidate();
  359. }
  360.                                                         
  361. ////////////////////////////////////////////////////////////////////////////////////////
  362. void CSerwebView::KillConn(int SockNumber)
  363.  
  364. {             
  365.    
  366.    WWWConv[SockNumber].State = SOCK_FREE; 
  367.    closesocket( WWWConv[SockNumber].CliSock );
  368.    if (WWWConv[SockNumber].SendFile.m_hFile != (UINT)CFile::hFileNull)
  369.       WWWConv[SockNumber].SendFile.Close();            // If there are problems, just ignore <-- Is this OK?
  370.    PrintSt("  Connection closed.\n");
  371. }
  372. ////////////////////////////////////////////////////////////////////////////////////////
  373. void CSerwebView::SendBlockOfData(int SockNumber)
  374. {           
  375.    int err;                                   
  376.   
  377.    while (1==1)
  378.     {
  379.       if (WWWConv[SockNumber].HowManyInSendBuf == 0)
  380.         {
  381.           WWWConv[SockNumber].HowManyInSendBuf = WWWConv[SockNumber].SendFile.Read(WWWConv[SockNumber].SendBuf, SEND_BUF_LEN);
  382.           WWWConv[SockNumber].OffsetToSend = 0;
  383.         } 
  384.         
  385.                 
  386.      WWWConv[SockNumber].LastTime = CTime::GetCurrentTime();        // Update time of last action ..
  387.       if (WWWConv[SockNumber].HowManyInSendBuf == 0)                                  // Lets guess that this is EOF for now.
  388.         {
  389.            PrintSt("  File sent OK -Terminating connection\n");
  390.            KillConn( SockNumber);
  391.            return;                                    // <--- ONE of 3 ways to get out
  392.         }          
  393.       else
  394.         {
  395.           err = send( WWWConv[SockNumber].CliSock, WWWConv[SockNumber].SendBuf+WWWConv[SockNumber].OffsetToSend, WWWConv[SockNumber].HowManyInSendBuf,0);    
  396.  
  397.              
  398.           if (err == SOCKET_ERROR)
  399.             {                    
  400.               if (WSAGetLastError() == WSAEWOULDBLOCK)
  401.                 {         
  402.                    #ifdef _DEBUG
  403.                      PrintSt("  *** Can't send all of the data at once - Pausing now\n");
  404.                    #endif
  405.                    return;                            // <--- second way to get out ..
  406.                 } 
  407.               else
  408.                {         
  409.                
  410.                   PrintSt("  *** Error while sending to the client some data.\n");
  411.                   KillConn( SockNumber );
  412.                   return;                                    // <--- last of 3 ways to get out
  413.                 }
  414.              }
  415.  
  416.           if (err != WWWConv[SockNumber].HowManyInSendBuf)
  417.             {
  418.               #ifdef _DEBUG
  419.                  PrintSt("  Did not send all data\n");
  420.               #endif
  421.               WWWConv[SockNumber].OffsetToSend = WWWConv[SockNumber].OffsetToSend + err;
  422.               WWWConv[SockNumber].HowManyInSendBuf = WWWConv[SockNumber].HowManyInSendBuf - err;
  423.             }
  424.            else
  425.              {
  426.                WWWConv[SockNumber].HowManyInSendBuf = 0;     // So we can get more data..
  427.                WWWConv[SockNumber].OffsetToSend = 0;         // Not needed (TRACE IT AND SEE WHY) but JIC (Just In Case)
  428.              }
  429.         }
  430.      }
  431. }    
  432.                                                         
  433.  
  434. ////////////////////////////////////////////////////////////////////////////////////////
  435. CString CSerwebView::GetFirstString(CString TheString, int WrdToGet)
  436.  
  437. {
  438.    int Count, StPos,EndPos;
  439.    
  440.    if (TheString.GetLength() == 0)
  441.      return CString("");
  442.    EndPos = -1;                // Just follow the logic.  TRUST ME !
  443.    Count = 0;
  444.    while (Count < WrdToGet)
  445.    {  
  446.      StPos=EndPos+1;
  447.      while ((StPos < TheString.GetLength()) && ((TheString[StPos]==' ') ||(TheString[StPos]=='\t'))) 
  448.        StPos++;
  449.      if (StPos == TheString.GetLength())
  450.        return CString("");
  451.      EndPos = StPos;
  452.      while ((EndPos < TheString.GetLength()) && (TheString[EndPos]!=' ') && (TheString[EndPos]!='\t')) 
  453.        EndPos++;
  454.      Count++;
  455.     }
  456.    return TheString.Mid(StPos, (EndPos-StPos));
  457. }
  458. ////////////////////////////////////////////////////////////////////////////////////////
  459. void CSerwebView::ProcessRequest(int SockNumber)
  460.  
  461. {
  462.    CString Testing;
  463.    int Count = 1, Loop, err;
  464.    CWnd* pParent = GetParent();
  465.    CMenu* pMenu = pParent->GetMenu();                   
  466.                       
  467.    // Get the first word ......
  468.    
  469.    Testing = GetFirstString( WWWConv[SockNumber].InBuf, 1);
  470.    
  471.    if ( Testing.CompareNoCase("GET") == 0)
  472.      {
  473.        Testing = GetFirstString( WWWConv[SockNumber].InBuf, 2);
  474.  
  475.        // Lets ensure the slash is OK for DOS  - Just in case
  476.        for (Loop = 0; Loop < Testing.GetLength(); Loop++)
  477.          if (Testing[Loop] == '/')
  478.             Testing.SetAt(Loop,'\\');
  479.        
  480.        if (Testing[0] != '\\')
  481.          Testing = SendDir + CString("\\")+ Testing;
  482.        else
  483.          Testing = SendDir + Testing;
  484.  
  485.        // See if we are closed and send a message.
  486.        if (pMenu->GetMenuState(ID_SERVER_INACT, MF_BYCOMMAND) == MF_CHECKED) 
  487.          { 
  488.            PrintSt("  Telling client server is off.\n");
  489.            Testing = ClosedServerMsg;
  490.           }
  491.           
  492.        // They want a file with .. - check to see if we allow ?
  493.        if (pMenu->GetMenuState(ID_PERIOD_OK, MF_BYCOMMAND) == MF_UNCHECKED)
  494.          if (Testing.Find("..") > -1)              // Found them ....
  495.            {  
  496.              PrintSt("  Telling server we do not allow .. on the URI.\n");
  497.              Testing = PeriodAllowedMsg;
  498.            }
  499.         PrintSt("  Trying to send file - ");
  500.         PrintSt(Testing);
  501.         PrintSt("\n");
  502.        
  503.        // Lets try to open the file now ......
  504.        if (!WWWConv[SockNumber].SendFile.Open(Testing, CFile::modeRead | CFile::typeBinary))
  505.          {
  506.              // We could not send the file ......
  507.              PrintSt("  File does not exist - Sending Message\n");
  508.              if (!WWWConv[SockNumber].SendFile.Open(FileNotExistMsg, CFile::modeRead | CFile::typeBinary))
  509.                 {
  510.                    // DAMM, That file dows not exist either ...
  511.  
  512.                    err = send( WWWConv[SockNumber].CliSock, "HTTP/1.0 404 The file requested was not found\n",46,0);    
  513.                    if (err == SOCKET_ERROR)
  514.                       PrintSt("  Error while sending to the client the 404 msg.\n");
  515.                    #ifdef _DEBUG
  516.                      PrintSt("  *** Socket will be closed now ....\n");
  517.                    #endif
  518.                    
  519.                    KillConn( SockNumber );  
  520.                  }
  521.                else
  522.                  {
  523.                     WWWConv[SockNumber].HowManyInSendBuf = 0;               // We have not sent any chars ....
  524.                     SendBlockOfData(SockNumber);
  525.                  }
  526.           }
  527.        else    
  528.         {           
  529.           WWWConv[SockNumber].HowManyInSendBuf = 0;               // We have not sent any chars ....
  530.           SendBlockOfData(SockNumber);
  531.          }
  532.       }
  533.   else
  534.     {
  535.        PrintSt("  Unrecognized method: ");
  536.        PrintSt(WWWConv[SockNumber].InBuf);
  537.        PrintSt("\n");
  538.        
  539.        err = send( WWWConv[SockNumber].CliSock, "HTTP/1.0 599 Unrecognized method request\n",41,0);    
  540.        if (err == SOCKET_ERROR)
  541.           PrintSt("  Error while sending to the client the 599 msg.\n");
  542.        
  543.        #ifdef _DEBUG
  544.          PrintSt("  *** Socket will be closed now ....\n");
  545.        #endif
  546.         
  547.        KillConn( SockNumber ); 
  548.      }
  549. }
  550.  
  551. ////////////////////////////////////////////////////////////////////////////////////////
  552. void CSerwebView::ProcessRead(int SockNumber)
  553.  
  554. {
  555.  int err, RdLoop;
  556.  u_long ulBytesToRead = 0L;
  557.  char Buf[200];
  558.    
  559.    if (WWWConv[SockNumber].State != WAITING)
  560.      {    
  561.        #ifdef _DEBUG
  562.           PrintSt("  *** The socket is trying to send information while we are in send mode. \n");
  563.        #endif
  564.        return;
  565.       }       
  566.    #ifdef _DEBUG   
  567.       PrintSt("  *** I am able read from the client now \n");
  568.    #endif
  569.           
  570.    ioctlsocket( WWWConv[SockNumber].CliSock, FIONREAD, &ulBytesToRead);
  571.           
  572.    while ((ulBytesToRead > 0L) && (WWWConv[SockNumber].State == WAITING))
  573.       {
  574.          // Just in case a nut desides to crash the thing ....
  575.          if (ulBytesToRead > 199)
  576.            ulBytesToRead = 200;                               
  577.           
  578.          err = recv( WWWConv[SockNumber].CliSock, Buf, (int) ulBytesToRead, 0);
  579.     
  580.          if (err == SOCKET_ERROR)
  581.                 {
  582.                    PrintSt("  An error ocurred when reading from the client \n");
  583.                    return;
  584.                 }        
  585.  
  586.               RdLoop = 0;
  587.               while (RdLoop < err)
  588.                 if ((Buf[RdLoop] == '\n') ||(Buf[RdLoop] == '\r') ||(Buf[RdLoop] == 0x0D) || (Buf[RdLoop] == 0x0A))
  589.                   {                                
  590.                     WWWConv[SockNumber].State = SENDING;
  591.                     break;
  592.                   }
  593.                 else            
  594.                   {
  595.                      WWWConv[SockNumber].InBuf += Buf[RdLoop]; 
  596.                      RdLoop++;
  597.                   }
  598.  
  599.               ioctlsocket( WWWConv[SockNumber].CliSock, FIONREAD, &ulBytesToRead);
  600.             }
  601.            
  602.         // If we received the request, lets address it .....
  603.           
  604.            #ifdef _DEBUG
  605.               PrintSt("  *** Got the following so far ->");
  606.               PrintSt(WWWConv[SockNumber].InBuf);
  607.               PrintSt("<---\n");
  608.            #endif
  609.            
  610.            if (WWWConv[SockNumber].State == SENDING)
  611.               {
  612.                 ProcessRequest(SockNumber);
  613.  
  614.               } 
  615.  
  616.  
  617. }
  618.  
  619. ////////////////////////////////////////////////////////////////////////////////////////
  620. LRESULT CSerwebView::OnWWWClientMsg(WPARAM wParam, LPARAM lParam)
  621.  
  622. {
  623. // int err, Loop, RdLoop;
  624.  int Loop;
  625.  u_long ulBytesToRead = 0L;
  626. // char Buf[200];
  627.  
  628.  
  629.  if (WSAGETSELECTERROR(lParam) == 00)
  630.    {
  631.  
  632.     // Lets get the socket that cried for help .....
  633.     
  634.      for (Loop = 0; Loop < HowManyClients; Loop++)
  635.          if (WWWConv[Loop].CliSock == (SOCKET) wParam)
  636.              break;
  637.  
  638.     // Just in case .....
  639.      if (Loop == HowManyClients)
  640.        {  
  641.           #ifdef _DEBUG
  642.              PrintSt("  *** A socket has cried but is not ours ????\n");
  643.           #endif
  644.           return 0L;
  645.        }
  646.  
  647.      if (WWWConv[Loop].State == SOCK_FREE)
  648.        {  
  649.           #ifdef _DEBUG
  650.              PrintSt("  *** A socket has cried but it is closed ????\n");
  651.           #endif
  652.           return 0L;
  653.        }
  654.      
  655.      WWWConv[ Loop ].LastTime = CTime::GetCurrentTime();        // Update time of last action ..
  656.      if (WSAGETSELECTEVENT(lParam) == FD_READ)
  657.        {                                       
  658.          ProcessRead( Loop );
  659.          return 0L;     
  660.             
  661.        }
  662.  
  663.      if (WSAGETSELECTEVENT(lParam) == FD_WRITE)
  664.        {      
  665.           #ifdef _DEBUG                                 
  666.              PrintSt("  *** I am able to write to the client now.\n");
  667.           #endif
  668.           if (WWWConv[Loop].State == SENDING)
  669.             {
  670.               SendBlockOfData(Loop);
  671.             }
  672.           return 0L;
  673.        }
  674.  
  675.      if (WSAGETSELECTEVENT(lParam) == FD_CLOSE)
  676.        {
  677.           PrintSt("  Connection terminated by client.\n");
  678.  
  679.           KillConn( Loop );
  680.           
  681.           return 0L;   
  682.        }
  683.    }                           
  684.  
  685.  return 0L;
  686. }
  687.  
  688. ////////////////////////////////////////////////////////////////////////////////////////
  689. LRESULT CSerwebView::OnWWWServerMsg(WPARAM wParam, LPARAM lParam)
  690.  
  691. {
  692.  WORD err;
  693.  int Loop;                        
  694.  SOCKADDR sad;      // Accept socket variables ......
  695.  int len = sizeof(sad);
  696.  SOCKET TempSock;                       
  697.  CFile  QFile;
  698.  
  699.  
  700.  if (WSAGETSELECTERROR(lParam) == 0)
  701.    {
  702.      if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT)
  703.        {
  704.           PrintSt("  Connection has arrived\n");
  705.  
  706.           for (Loop = 0; Loop < HowManyClients; Loop++)
  707.              if (WWWConv[Loop].State == SOCK_FREE)
  708.                break;
  709.  
  710.           if (Loop == HowManyClients)
  711.             {
  712.               PrintSt("  Maximun number of incoming connections reached.\n  Notifying request to try on a few seconds.\n");
  713.               
  714.               TempSock = accept(WWWServer, &sad, &len);
  715.               if (TempSock == INVALID_SOCKET)
  716.                 {
  717.                   PrintSt("  Could not accept the temporary socket.\n");
  718.                   return 0L;
  719.                 }
  720.  
  721.               WSAAsyncSelect(TempSock, m_hWnd, 0, 0);       // Lets go raw !!! & pray (????)
  722.               err = send( TempSock, "HTTP/1.0 400 Unable to satisfy request now - TRY IN A FEW SECONDS !!!\n",69,0);    
  723.               if (err == SOCKET_ERROR)
  724.                 PrintSt("  Error while sending notice to temporary socket.\n");
  725.  
  726.               closesocket( TempSock );
  727.              
  728.               return 0L;          // Get out ....
  729.             }
  730.            WWWConv[Loop].InBuf = "";
  731.           WWWConv[Loop].State = WAITING;
  732.           WWWConv[Loop].CliSock = accept(WWWServer, &sad, &len);
  733.           if (WWWConv[Loop].CliSock == INVALID_SOCKET)
  734.              {
  735.                PrintSt("  Could not accept the incoming connection.\n");
  736.                WWWConv[Loop].State = SOCK_FREE;
  737.                return 0L;
  738.              }
  739.           err = WSAAsyncSelect(WWWConv[Loop].CliSock, m_hWnd, CLIENT_MSG, FD_READ | FD_WRITE | FD_CLOSE);
  740.           if (err == SOCKET_ERROR) 
  741.              {
  742.                sprintf(buf, "  Windows Socket error %d:  WSAAsyncSelect code did not work while accepting connection\n", WSAGetLastError());
  743.                PrintSt(buf); 
  744.                KillConn( Loop );
  745.                return 0L;
  746.              } 
  747.  
  748.           
  749.           //  Important ..   
  750.           ProcessRead(Loop);         // <---- WHY IS THIS NEEDED ???? SOME TIMES I DON'T RECEIVE FD_READ MSG (GUS)
  751.           
  752.           #ifdef _DEBUG
  753.              PrintSt("  *** Waiting for input from the client now.\n");
  754.           #endif
  755.          
  756.          
  757.          }  
  758.  
  759.     }
  760.  
  761.  return 0L;
  762. }
  763.  
  764. // Menu updates below .................................................
  765. void CSerwebView::OnPeriodOk()
  766. {
  767.   CWnd* pParent = GetParent();
  768.   CMenu* pMenu = pParent->GetMenu();                   
  769.        
  770.    if (pMenu->GetMenuState(ID_PERIOD_OK, MF_BYCOMMAND) == MF_UNCHECKED) 
  771.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_CHECKED);
  772.    else
  773.       pMenu->CheckMenuItem(ID_PERIOD_OK, MF_UNCHECKED);
  774. }
  775.  
  776. void CSerwebView::OnServerInact()
  777. {
  778.   CWnd* pParent = GetParent();
  779.   CMenu* pMenu = pParent->GetMenu();                   
  780.        
  781.    if (pMenu->GetMenuState(ID_SERVER_INACT, MF_BYCOMMAND) == MF_UNCHECKED) 
  782.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_CHECKED);
  783.    else
  784.       pMenu->CheckMenuItem(ID_SERVER_INACT, MF_UNCHECKED);
  785. }
  786.  
  787. void CSerwebView::OnUpdateStat()
  788. {
  789.   CWnd* pParent = GetParent();
  790.   CMenu* pMenu = pParent->GetMenu();                   
  791.        
  792.    if (pMenu->GetMenuState(ID_UPDATE_STAT, MF_BYCOMMAND) == MF_UNCHECKED) 
  793.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_CHECKED);
  794.    else
  795.       pMenu->CheckMenuItem(ID_UPDATE_STAT, MF_UNCHECKED);
  796. }
  797.  
  798. ///////////////////////////////////////////////////////////////////////////////////////
  799. void CSerwebView::OnTimer(UINT nIDEvent)
  800. {
  801.   int Loop; 
  802.   CTimeSpan TimeDiff; 
  803.   CTime     TheTimeNow;
  804.     
  805.     #ifdef _DEBUG
  806.       PrintSt("  *** Servicing the timer now\n");
  807.     #endif
  808.     for (Loop = 0; Loop < HowManyClients; Loop++) 
  809.       {
  810.        if (WWWConv[Loop].State != SOCK_FREE)
  811.          {
  812.             TimeDiff = CTime::GetCurrentTime() - WWWConv[Loop].LastTime;
  813.             #ifdef _DEBUG
  814.                afxDump << "Time now - " << TheTimeNow << " Lats time - " << WWWConv[Loop].LastTime << " Time diff - " << TimeDiff.GetTotalMinutes() << "\n";
  815.             #endif
  816.             if ((int) TimeDiff.GetTotalMinutes() > INACTIVE)
  817.               {
  818.                  PrintSt("  Connections has not responded for the last 3 minutes.\n");
  819.                  KillConn( Loop );                                                    
  820.               }
  821.          }
  822.       } 
  823. }
  824.